// ----------------------------------------------------------
// This Source Code Form is subject to the terms of the
// Mozilla Public License, v.2.0. If a copy of the MPL
// was not distributed with this file, You can obtain one
// at http://mozilla.org/MPL/2.0/.
// ----------------------------------------------------------
// Codebase: https://github.com/ArKuznetsov/cpdb/
// ----------------------------------------------------------

#Использовать yadisk
#Использовать fs

Перем Токен;           // - Строка        - токен авторизации Yandex-диска
Перем Соединение;      // - ЯндексДиск    - соединение с сервером YandexDisk

Перем Лог;             // - Объект    - объект записи лога приложения

#Область ПрограммныйИнтерфейс

// Функция - возвращает соединение с Yandex-диском
//
// Возвращаемое значение:
//   ЯндексДиск    - соединение с Yandex-диском
//
Функция Соединение() Экспорт

	Возврат Соединение;

КонецФункции // Соединение()

// Создает соединение с Yandex-диском с указанными параметрами
//
// Параметры:
//    _Токен    - Строка    - токен авторизации Yandex-диска
//
Процедура УстановитьПараметрыСоединения(Знач _Токен) Экспорт

	Токен = _Токен;

	Соединение = Новый ЯндексДиск();
	Соединение.УстановитьТокенАвторизации(Токен);

КонецПроцедуры // УстановитьПараметрыСоединения()

// Процедура - Создает каталог на Yandex-диске
//
// Параметры:
//   ЦелевойПуть    - ЯндексДиск    - путь на yandex-диске к создаваемому каталогу
//
Процедура СоздатьКаталог(Знач ЦелевойПуть) Экспорт

	КаталогНайден = Ложь;
	Попытка
		СвойстваПапки = Соединение.ПолучитьСвойстваРесурса(ЦелевойПуть);
		КаталогНайден = Истина;
	Исключение
		СвойстваПапки = Новый Структура("type", "dir");
	КонецПопытки;

	Если СвойстваПапки["type"] <> "dir" Тогда
		ТекстОшибки = СтрШаблон("Ошибка при создании каталога ""%1"" на Yandex-Диске", ЦелевойПуть);
		ВызватьИсключение ТекстОшибки;
	КонецЕсли;

	Если НЕ КаталогНайден Тогда
		Попытка
			Соединение.СоздатьПапку(ЦелевойПуть);
			Лог.Информация("Создан каталог ""%1"" на Yandex-Диске", ЦелевойПуть);
		Исключение
			ТекстОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
			ТекстОшибки = СтрШаблон("Ошибка при создании каталога ""%1"" на Yandex-Диске: %2%3",
			                        ЦелевойПуть,
			                        Символы.ПС,
			                        ТекстОшибки);
			ВызватьИсключение ТекстОшибки;
		КонецПопытки;
	КонецЕсли;
	
КонецПроцедуры // СоздатьКаталог()

// Функция отправки файла на Yandex-Диск
//
// Параметры:
//   ПутьКФайлу     - Строка        - путь к отправляемому файлу
//   ЦелевойПуть    - Строка        - путь на yandex-диске, куда будет загружен файл
//   Перезаписывать - Булево        - перезаписать файл на Яндекс-диске при загрузке
//
Процедура ОтправитьФайл(Знач ПутьКФайлу, Знач ЦелевойПуть, Перезаписывать = Ложь) Экспорт
	
	ПутьКФайлу = ФС.ПолныйПуть(ПутьКФайлу);

	Лог.Информация("Начало отправки файла на yandex-диск ""%1"" -> ""%2""", ПутьКФайлу, ЦелевойПуть);

	СвойстваДиска = Соединение.ПолучитьСвойстваДиска();
	Лог.Отладка("Всего доступно %1 байт", СвойстваДиска.total_space);
	Лог.Отладка("Из них занято %1 байт", СвойстваДиска.used_space);
	
	СвободноМеста = СвойстваДиска.total_space - СвойстваДиска.used_space;

	ИсходныйФайл = Новый Файл(ПутьКФайлу);
	ИмяЗагружаемогоФайла = СтрШаблон("%1/%2", ЦелевойПуть, ИсходныйФайл.Имя);
	
	РазмерФайла = ИсходныйФайл.Размер();
	
	Если СвободноМеста < РазмерФайла Тогда
		ТекстОшибки = СтрШаблон("Недостаточно места на Yandex-диск для копирования файла ""%1"": есть %2, надо %3",
		                        ПутьКФайлу,
		                        СвободноМеста,
		                        РазмерФайла);
		ВызватьИсключение ТекстОшибки;
	КонецЕсли;
	
	Попытка
		Соединение.ЗагрузитьНаДиск(ИсходныйФайл.ПолноеИмя, ИмяЗагружаемогоФайла, Перезаписывать);
		Лог.Информация("Файл загружен на yandex-диск ""%1"" -> ""%2""", ПутьКФайлу, ЦелевойПуть);
	Исключение
		ТекстОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
		ТекстОшибки = СтрШаблон("Ошибка загрузки файла ""%1"" в %2:%3%4",
		                        ИсходныйФайл.Имя,
		                        ИмяЗагружаемогоФайла,
		                        Символы.ПС,
		                        ТекстОшибки);
		ВызватьИсключение ТекстОшибки;
	КонецПопытки;

	Попытка
		Соединение.ПолучитьСвойстваРесурса(ИмяЗагружаемогоФайла);
	Исключение
		ТекстОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
		ТекстОшибки = СтрШаблон("Ошибка при получении свойств файла %1:%2%3",
		                        ИмяЗагружаемогоФайла,
		                        Символы.ПС,
		                        ТекстОшибки);
		ВызватьИсключение ТекстОшибки;
	КонецПопытки;
	
КонецПроцедуры // ОтправитьФайл()

// Функция получения файла из Yandex-Диска
//
// Параметры:
//   ПутьНаДиске        - Строка        - расположение файла на yandex-диске
//   ЦелевойПуть        - Строка        - путь, куда будет загружен файл
//   УдалитьИсточник    - Булево        - Истина - удалить файл после загрузки
//
// Возвращаемое значение:
//   Число - код возврата команды
//
Функция ПолучитьФайл(Знач ПутьНаДиске, Знач ЦелевойПуть, УдалитьИсточник = Ложь) Экспорт
	
	ЦелевойПуть = ФС.ПолныйПуть(ЦелевойПуть);

	Лог.Информация("Начало получения файла ""%1"" -> ""%2""", ПутьНаДиске, ЦелевойПуть);

	ПутьКСкачанномуФайлу = "";
	
	Попытка
		ПутьКСкачанномуФайлу = Соединение.СкачатьФайлСДиска(ЦелевойПуть, ПутьНаДиске, Истина);

		Лог.Информация("Файл получен %1", ПутьКСкачанномуФайлу);
	Исключение
		ТекстОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
		ТекстОшибки = СтрШаблон("Ошибка получения файла ""%1"": %2%3",
		                        ПутьНаДиске,
		                        Символы.ПС,
		                        ТекстОшибки);
		ВызватьИсключение ТекстОшибки;
	КонецПопытки;

	Если УдалитьИсточник Тогда
		Удалить(ПутьНаДиске);
		СвойстваДиска = Соединение.ПолучитьСвойстваДиска();
		Лог.Отладка("Всего доступно %1 байт", СвойстваДиска.total_space);
		Лог.Отладка("Из них занято %1 байт", СвойстваДиска.used_space);
	КонецЕсли;
	
	Возврат ПутьКСкачанномуФайлу;

КонецФункции // ПолучитьФайл()

// Функция - проверяет существование файла / каталога на Yandex-Диске
//
// Параметры:
//   ПутьНаДиске    - Строка    - расположение файла на Yandex-Диске
//
// Возвращаемое значение:
//   Булево    - Истина - файл / каталог существует
//
Функция Существует(Знач ПутьНаДиске) Экспорт

	Лог.Информация("Начало проверки существования файла / каталога  ""%1""", ПутьНаДиске);

	КаталогИлиФайлНайден = Ложь;

	Попытка
		СвойстваФайлаИлиПапки = Соединение.ПолучитьСвойстваРесурса(ПутьНаДиске);

		Если СвойстваФайлаИлиПапки["type"] = "dir" ИЛИ СвойстваФайлаИлиПапки["type"] = "file" Тогда
			КаталогИлиФайлНайден = Истина;
			Лог.Информация("Файл / каталог существует ""%1""", ПутьНаДиске);
		КонецЕсли;	
	Исключение
		Лог.Информация("Файл / каталог не существует ""%1""", ПутьНаДиске);
	КонецПопытки;

	Возврат КаталогИлиФайлНайден;	

КонецФункции // Существует()

// Процедура - удаляет файл из Yandex-Диска
//
// Параметры:
//   ПутьНаДиске    - Строка    - расположение файла на Yandex-Диске
//
Процедура Удалить(Знач ПутьНаДиске) Экспорт
	
	Попытка
		Соединение.Удалить(ПутьНаДиске, Истина);

		Лог.Информация("Удален файл ""%1"" из Yandex-Диска", ПутьНаДиске);
	Исключение
		ТекстОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
		ТекстОшибки = СтрШаблон("Ошибка удаления файла ""%1"" из Yandex-Диска: %2%3",
		                        ПутьНаДиске,
		                        Символы.ПС,
		                        ТекстОшибки);
		ВызватьИсключение ТекстОшибки;
	КонецПопытки;

КонецПроцедуры // Удалить()

#КонецОбласти // ПрограммныйИнтерфейс

#Область ОбработчикиСобытий

// Процедура - обработчик события "ПриСозданииОбъекта"
//
// Параметры:
//    _Токен    - Строка    - токен авторизации Yandex-диска
//
// BSLLS:UnusedLocalMethod-off
Процедура ПриСозданииОбъекта(Знач _Токен) Экспорт

	Лог = ПараметрыСистемы.Лог();

	УстановитьПараметрыСоединения(_Токен);

КонецПроцедуры // ПриСозданииОбъекта()
// BSLLS:UnusedLocalMethod-on

#КонецОбласти // ОбработчикиСобытий
